package org.dragonnova.business.web;

import java.beans.PropertyEditorSupport;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringEscapeUtils;
import org.dragonnova.business.cache.EhCacheBean;
import org.dragonnova.business.common.Constants;
import org.dragonnova.business.message.mq.kafka.KafkaMessageListener;
import org.dragonnova.business.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.ModelAndView;

import com.base.pub.mapper.SimpleJsonMapper;
import com.base.pub.util.DateUtils;
import com.base.pub.util.StringUtils;

public abstract class BaseController {

	private final static Logger logger = LoggerFactory
			.getLogger(BaseController.class);

	public String renderString(HttpServletResponse response, Object object) {
		return renderString(response, SimpleJsonMapper.toJsonStr(object),
				"application/json");
	}

	@Autowired
	private EhCacheBean ehCache;

	@Autowired
	private KafkaMessageListener kafkaMessageListener;

	@ExceptionHandler({ BindException.class })
	public String bindException() {
		return "error/error";
	}

	@ExceptionHandler({ Exception.class })
	public ModelAndView authenticationException(HttpServletRequest request,
			HttpServletResponse resp, Exception e) {
		if (logger.isDebugEnabled())
			logger.debug(e.getMessage(), e);

		return new ModelAndView("error/error").addObject("error_message",
				e.getMessage());
	}

	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
			@Override
			public void setAsText(String text) {
				setValue(text == null ? null : StringEscapeUtils
						.escapeHtml4(text.trim()));
			}

			@Override
			public String getAsText() {
				Object value = getValue();
				return value != null ? value.toString() : "";
			}
		});
		binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
			@Override
			public void setAsText(String text) {
				setValue(DateUtils.parseDate(text));
			}
		});
	}

	private String renderString(HttpServletResponse response, String value,
			String type) {
		try {
			response.setContentType(type);
			response.setCharacterEncoding("utf-8");
			response.getWriter().print(value);
			return value;
		} catch (IOException e) {
			return null;
		}
	}

	/**
	 * 当前登录的用户信息
	 * 
	 * @param session
	 * @param user
	 */
	public void setLoginUser(HttpSession session, User user) {
		session.setAttribute(Constants.LOGIN_KEY, user);
		session.setAttribute("userName", user.getUsername());
		session.setAttribute(Constants.VALIDATE_SESSION_TOKEN, true);

		user.setLogin_time(DateUtils.getTimes(session.getLastAccessedTime(),
				DateUtils.FORMAT_DATE_1));
		// 缓存用户
		ehCache.save(Constants.USER_CACHE_NAME, session.getId(), user);
		// 开启消息
		startMessage(Long.toString(user.getId()));
	}

	public User getLoginUser(HttpSession session) {
		Object obj = session.getAttribute(Constants.LOGIN_KEY);
		if (obj instanceof User) {
			return (User) obj;
		} else {
			return null;
		}
	}

	/**
	 * 管理员 ： sql语句中判断userId==null 时去掉where userId条件
	 * 
	 * @param session
	 * @param confirm是否需要验证管理员
	 * @return
	 */
	public Integer getUserId(HttpSession session, boolean confirm) {
		User user = getLoginUser(session);
		if (user == null) {
			return null;
		} else if (confirm && isAdmin(user)) {
			return -10;
		} else {
			return user.getId();
		}
	}

	/**
	 * 验证管理员
	 * 
	 * @param user
	 * @return
	 */
	private boolean isAdmin(User user) {
		return user.getGid() == 1;
	}

	/**
	 * 提示异常
	 */
	public Map<String, Object> warnException(Exception e) {
		Map<String, Object> map = new HashMap<>();
		map.put("result", -3);
		map.put("message", "网络异常！");
		map.put("Exception", e.getMessage());
		return map;
	}

	/**
	 * 封装数据
	 */
	@SuppressWarnings("rawtypes")
	public Map<String, Object> packData(Object obj) {
		Map<String, Object> map = new HashMap<>();
		map.put("result", 0);
		map.put("data", obj);
		if (obj instanceof List) {
			map.put("count", ((List) obj).size());
		}
		map.put("message", "查询成功！");
		return map;
	}

	public Map<String, Object> packSaveInfo(boolean success) {
		return packInfo(success, "保存");
	}

	public Map<String, Object> packDelInfo(boolean success) {
		return packInfo(success, "删除");
	}

	public Map<String, Object> packInfo(boolean success, String info) {
		Map<String, Object> map = new HashMap<>();
		if (success) {
			map.put("result", 0);
			String msg = StringUtils.concat(info, "成功！");
			map.put("message", msg);
		} else {
			map.put("result", -1);
			String msg = StringUtils.concat(info, "失败！");
			map.put("message", msg);
		}
		return map;
	}

	public Map<String, Object> bindingResult(BindingResult result) {
		Map<String, Object> map = new HashMap<>();
		List<ObjectError> list = result.getAllErrors();
		List<String> errors = new ArrayList<>();
		for (int i = 0; i < list.size(); i++) {
			ObjectError error = list.get(i);
			errors.add(error.getDefaultMessage());
		}
		map.put("error", errors);
		map.put("result", -2);
		map.put("message", "参数异常！");
		return map;
	}

	private void startMessage(String userIdString) {
		kafkaMessageListener.start(userIdString);
	}

	protected void stopMessage() {
		kafkaMessageListener.stop();
	}

}
